#Works on the following games:
#Star guardian
#Star Guardian 2
#Arena Champion
#Arena Champion 2

import os, sys
from Sanae3D.lib.ModelObject import Model3D
from Sanae3D.lib.StructReader import StructReader

class magicdbo_DBO(Model3D):
    '''Replace 'magicdbo_DBO' with a suitable name of your choice. Try to follow
    the standard: GameName_FormatExt'''
    
    def __init__(self, obj3D=None, outFile=None, inFile=None):
        
        super(magicdbo_DBO,self).__init__("DBO")
        self.obj3D = obj3D
        self.inFile = inFile
        self.outFile = outFile
        
    def parse_faces(self, meshName, numFaces, meshNum):
        
        for i in range(numFaces):            
            v1, v2, v3 = self.inFile.read_short(3)
            
            self.create_face(meshName, i)
            self.add_face_verts(meshName, i, [v1, v2, v3])
            self.add_face_material(meshName, i, meshNum)
            
    def parse_vertices(self, meshName, numVerts):
        
        for i in range(numVerts):
            vx, vy, vz = self.inFile.read_float(3)
            nx, ny, nz = self.inFile.read_float(3)
            tu, tv = self.inFile.read_float(2)
            
            vx = float(vx) * -1
            self.create_vertex(meshName, i)
            self.add_coords(meshName, i, [vx, vy, vz])
            self.add_vert_uv(meshName, i, [tu, tv])
            self.add_vert_normals(meshName, i, [nx, ny, nz])
        
    def parse_mesh(self, chunkSize):
        
        sectEnd = self.inFile.tell() + chunkSize
        
        while self.inFile.tell() != sectEnd:
            chunk = self.inFile.read_long()
            chunkSize = self.inFile.read_long()
            print hex(chunk), chunkSize, self.inFile.tell()
            if chunk == 0x65:
                charLen = self.inFile.read_long()
                name = self.inFile.read_string(charLen)
            elif chunk == 0x66:
                self.inFile.read_float(16)
            elif chunk == 0x67:
                #if not name:
                
                if chunkSize > 8:
                    meshNum = self.mesh_count()
                    if not name:
                        name = "obj[%d]" %meshNum
                    print name
                    self.create_object(name)
                    self.inFile.read_long(5)
                    vertSize = self.inFile.read_long()
                    self.inFile.read_long(2)
                    numVerts = self.inFile.read_long()                    
                    self.inFile.read_long(2)
                    numFaces = self.inFile.read_long() / 3
                    self.inFile.read_long(3)                    
                    vertChunk = self.inFile.read_long()
                    vertChunkSize = self.inFile.read_long()
                    self.parse_vertices(name, numVerts)

                    faceChunk = self.inFile.read_long()
                    faceChunkSize = self.inFile.read_long()
                    self.parse_faces(name, numFaces, meshNum)
                else:
                    self.inFile.read_long(2)
            elif chunk == 0x68:
                pass
            elif chunk == 0x69:
                pass
            elif chunk == 0x80:
                self.parse_material(chunkSize)
            else:
                self.inFile.seek(chunkSize, 1)
                
        
    def parse_file(self):
        '''Main parser method. Can be replaced'''
        
        filesize = self.inFile.filesize()
        charLen = self.inFile.read_long()
        magic = self.inFile.read_string(charLen)
        unk = self.inFile.read_long() #0x0426
        
        while self.inFile.tell() != filesize:
            chunk = self.inFile.read_long()
            chunkSize = self.inFile.read_long()
            
            if chunk == 0x00:
                self.inFile.seek(chunkSize, 1)
            elif chunk == 0x01: #start frame
                #self.parse_mesh(chunkSize)
                print "==Mesh start=="
            elif chunk == 0x02:
                self.inFile.seek(chunkSize, 1)
            elif chunk == 0x65:
                charLen = self.inFile.read_long()
                name = self.inFile.read_string(charLen)
            elif chunk == 0x66:
                self.inFile.read_float(16)
            elif chunk == 0x67:
                if chunkSize > 8:
                    meshNum = self.mesh_count()
                    if not name:
                        name = "obj[%d]" %meshNum
                    print name
                    self.create_object(name)
                    self.inFile.read_long(5)
                    vertSize = self.inFile.read_long()
                    self.inFile.read_long(2)
                    numVerts = self.inFile.read_long()                    
                    self.inFile.read_long(2)
                    numFaces = self.inFile.read_long() / 3
                    self.inFile.read_long(3)
                    vertChunk = self.inFile.read_long()
                    vertChunkSize = self.inFile.read_long()
                    self.parse_vertices(name, numVerts)
                    faceChunk = self.inFile.read_long()
                    faceChunkSize = self.inFile.read_long()
                    self.parse_faces(name, numFaces, meshNum)
            elif chunk == 0x68:
                pass
            elif chunk == 0x80:
                #material
                print "==material=="
            elif chunk == 0x8D:
                #texture
                print self.inFile.tell()
                charLen = self.inFile.read_long()
                texName = self.inFile.read_string(charLen)
                print texName
            else:
                print "unk chunk", hex(chunk)
                self.inFile.seek(chunkSize, 1)
        
def read_file(path):
    '''Read the file'''
    
    openFile = StructReader(open(path, 'rb'))
    obj = magicdbo_DBO(inFile=openFile)
    obj.parse_file()
    openFile.close()
    return obj

def write_file(path):
    
    pass

def definitions():
    '''Return the header, extension, and a description of the format'''
    
    return "", "DBO", ""

if __name__ == '__main__':
    
    file1 = "beer bottle.dbo"
    file2 = "gloves.dbo"
    file3 = "bed1.dbo"
    
    obj = read_file(file1)